package com.yxx.business.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yxx.business.entity.*;
import com.yxx.business.service.ITbEngineeringService;
import com.yxx.business.service.ITbEquipmentConfigService;
import com.yxx.business.service.ITbProjectEngineeringService;
import com.yxx.common.annotation.DataScope;
import com.yxx.common.core.utils.StreamUtils;
import com.yxx.common.utils.DateUtils;
import com.yxx.common.core.domain.PageResult;
import com.yxx.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import com.yxx.common.core.service.impl.ServiceImplPlus;
import com.yxx.business.mapper.TbProjectInfoMapper;
import com.yxx.business.service.ITbProjectInfoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 项目信息Service业务层处理
 *
 * @author yxx
 * @date 2025-08-03
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Lazy, @Autowired})
public class TbProjectInfoServiceImpl extends ServiceImplPlus<TbProjectInfoMapper, TbProjectInfoDo> implements ITbProjectInfoService {

    private final ITbProjectInfoService self;

    private final TbProjectInfoMapper tbProjectInfoMapper;

    private final ITbEngineeringService tbEngineeringService;

    private final ITbProjectEngineeringService tbProjectEngineeringService;

    private final ITbEquipmentConfigService tbEquipmentConfigService;

    /**
     * 查询项目信息分页结果
     *
     * @param tbProjectInfoQueryDto 项目信息查询实体
     * @return 项目信息分页
     */
    @Override
    public PageResult<TbProjectInfoVo> selectTbProjectInfoVoPage(TbProjectInfoQueryDto tbProjectInfoQueryDto) {
        startPage();
        List<TbProjectInfoVo> tbProjectInfoVos = self.selectTbProjectInfoVoList(tbProjectInfoQueryDto);
        PageResult<TbProjectInfoVo> page
                = super.getMyBatisPageResult(super.convertList(tbProjectInfoVos, TbProjectInfoVo.class));
        clearPage();
        // 获取所有项目的碳排放量
        if (StringUtils.isNotNull(page.getRows())) {
            List<Long> list = StreamUtils.toList(page.getRows(), TbProjectInfoVo::getProjectId);
            List<TbProjectEngineeringDo> projectEngineeringList =
                    tbProjectEngineeringService.list(new LambdaQueryWrapper<TbProjectEngineeringDo>().in(TbProjectEngineeringDo::getProjectId, list));
            if (StringUtils.isNotNull(projectEngineeringList)) {
                Map<Long, TbProjectInfoVo> map = StreamUtils.toMap(page.getRows(), TbProjectInfoVo::getProjectId, Function.identity());
                projectEngineeringList.forEach(projectEngineeringDo -> {
                    List<TbEquipmentPhaseVo> phaseAll = tbEquipmentConfigService.getPhaseAll(new TbEquipmentPhaseDto()
                            .setProjectId(projectEngineeringDo.getProjectId())
                            .setEngineeringId(projectEngineeringDo.getEngineeringId()));
                    List<BigDecimal> result = StreamUtils.toList(phaseAll, TbEquipmentPhaseVo::getTotalEmission);
                    // 结果进行相加
                    BigDecimal totalSum = result.stream()
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    map.get(projectEngineeringDo.getProjectId()).setTotalEmission(totalSum);
                });
            }
        }
        return page;
    }

    /**
     * 查询项目信息Vo列表
     *
     * @param tbProjectInfoQueryDto 项目信息查询实体
     * @return 项目信息集合
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<TbProjectInfoVo> selectTbProjectInfoVoList(TbProjectInfoQueryDto tbProjectInfoQueryDto) {
        return super.convertList(tbProjectInfoMapper.selectTbProjectInfoList(tbProjectInfoQueryDto), TbProjectInfoVo.class);
    }

    /**
     * 查询项目信息Do列表
     *
     * @param tbProjectInfoQueryDto 项目信息查询实体
     * @return 项目信息集合
     */
    @Override
    public List<TbProjectInfoDo> selectTbProjectInfoDoList(TbProjectInfoQueryDto tbProjectInfoQueryDto) {
        return tbProjectInfoMapper.selectTbProjectInfoList(tbProjectInfoQueryDto);
    }

    /**
     * 查询单个项目信息
     *
     * @param projectId 项目信息主键
     * @return 项目信息单个
     */
    @Override
    public TbProjectInfoVo selectTbProjectInfoVoByProjectId(Long projectId) {
        return super.convertBean(tbProjectInfoMapper.selectTbProjectInfoByProjectId(projectId), TbProjectInfoVo.class);
    }

    /**
     * 新增项目信息
     *
     * @param tbProjectInfoQueryDto 项目信息编辑实体
     * @return 结果
     */
    @Override
    public int insertTbProjectInfo(TbProjectInfoEditDto tbProjectInfoQueryDto) {
        tbProjectInfoQueryDto.setCreateBy(getUserNameOrNotLogged());
        tbProjectInfoQueryDto.setCreateTime(DateUtils.getNowDate());
        return tbProjectInfoMapper.insertTbProjectInfo(super.convertT(tbProjectInfoQueryDto).setCreateById(getUserIdOrNotLogged()));
    }

    /**
     * 修改项目信息
     *
     * @param projectId 项目信息主键
     * @param tbProjectInfoQueryDto 项目信息编辑实体
     * @return 结果
     */
    @Override
    public int updateTbProjectInfo(Long projectId, TbProjectInfoEditDto tbProjectInfoQueryDto) {
        tbProjectInfoQueryDto.setUpdateBy(getUserNameOrNotLogged());
        tbProjectInfoQueryDto.setUpdateTime(DateUtils.getNowDate());
        return tbProjectInfoMapper.updateTbProjectInfo(super.convertT(tbProjectInfoQueryDto).setProjectId(projectId));
    }

    /**
     * 批量删除项目信息
     *
     * @param projectIds 需要删除的项目信息主键集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteTbProjectInfoByProjectIds(List<Long> projectIds) {
        List<TbProjectEngineeringDo> list = tbProjectEngineeringService
                .list(new LambdaQueryWrapper<TbProjectEngineeringDo>().in(TbProjectEngineeringDo::getProjectId, projectIds));
        if (StringUtils.isNotEmpty(list)) {
            tbEngineeringService.deleteTbEngineeringByEngineeringIds(list.stream()
                    .map(TbProjectEngineeringDo::getEngineeringId)
                    .collect(Collectors.toList()));
        }
        return tbProjectInfoMapper.deleteTbProjectInfoByProjectIds(projectIds);
    }

    /**
     * 删除单个项目信息信息
     *
     * @param projectId 项目信息主键
     * @return 结果
     */
    @Override
    public int deleteTbProjectInfoByProjectId(Long projectId) {
        return tbProjectInfoMapper.deleteTbProjectInfoByProjectId(projectId);
    }
}
